; DESCRIPTION:
; Vertex shader used to render A3DSkinMesh. this shader does below works:
; # vertex blending (4 blending matrix) and transform
; # compute light = ambient + dir_light(ambient & diffuse) + point_light(ambient & diffuse)
; # output texture coordinates

; CREATED BY: duyuxin, 2003/10/28
; Copyright (c) 2003 Archosaur Studio, All Rights Reserved.

vs.1.1

;------------------------------------------------------------------------------
; v0 = position
; v1 = blend weights
; v2 = blend indices
; v3 = normal
; v7 = texture coordinates
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; Constants specified by the app;
;
; >= c14  = palette of world matrices (from model space to world space)
; c13	  = point_light's attenuation
; c12	  = material ambient * point_light.ambient
; c11	  = material.diffuse * point_light.diffuse
; c10	  = point_light's position in world space
; c9	  = material.specular * dir_light.specular
; c8	  = material.diffuse * dir_light.diffuse
; c7	  = ambient color + emmisive color
; c6	  = eye's direction in world space
; c2-c5   = view matrix * projection matrix (from world space to cuboid space)
; c1	  = dir_light's direction in world space
; c0	  = {1, power, 0, 765.01};
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
; oPos	  = Output position
; oD0	  = Diffuse
; oD1	  = Specular
; oT0	  = texture coordinates
;------------------------------------------------------------------------------

; ============ Transform position and normal from model space to world space ==========

; Compensate for lack of UBYTE4 on Geforce3
mul r1, v2.zyxw, c0.wwww
; mul r1,v2, c0.wwww

; first compute the last blending weight
dp3 r0.w, v1.xyz, c0.xxx
add r0.w, -r0.w, c0.x

; Set 1
mov a0.x, r1.x
m4x3 r4, v0, c[a0.x + 14]
m3x3 r5, v3, c[a0.x + 14] 

; blend them
mul r4, r4, v1.xxxx
mul r5, r5, v1.xxxx

; Set 2
mov a0.x, r1.y
m4x3 r2, v0, c[a0.x + 14]
m3x3 r3, v3, c[a0.x + 14]

; add them in
mad r4,r2,v1.yyyy,r4
mad r5,r3,v1.yyyy,r5
		
; Set 3
mov a0.x, r1.z
m4x3 r2, v0, c[a0.x + 14]
m3x3 r3, v3, c[a0.x + 14]

; add them in
mad r4, r2, v1.zzzz, r4
mad r5, r3, v1.zzzz, r5

; Set 4
mov a0.x, r1.w
m4x3 r2, v0, c[a0.x + 14]
m3x3 r3, v3, c[a0.x + 14]

; add them in
mad r4, r2, r0.wwww, r4
mad r5, r3, r0.wwww, r5

; Transfrom position from world space to cuboid space and output it
mov r4.w, c0.x
m4x4 oPos, r4, c2

; normalize normal
dp3 r5.w, r5, r5
rsq r5.w, r5.w
mul r5, r5, r5.w

; ============ Calculate dynamic point light's diffuse ============

; point light pos - vertex position in world space
add r10.xyz, c10, -r4.xyz

; Normalize vector VERTEX_TO_LIGHT and calculate distance
; d = distance
dp3 r10.w, r10, r10  	; r10.w = d * d = (x*x) + (y*y) + (z*z)
rsq r11.w, r10.w     	; r11.w = 1 / d = 1 / ||V|| = 1 / sqrt(r10.w)
mul r11, r10, r11.w	; r11 = Normalized vector

mov r8, c0.zzzz		; clear r8
dp3 r8.x, r5, r11 	; N dot L
lit r8, r8		; compute light

; Calculate the attenuation
; r10.w = d * d
; r11.w = 1 / d
; r9 = (1, d*d*1/d, d*d, 1/d)
dst r9, r10.w, r11.w

dp3 r9.x, r9, c13	; (a0 + a1*d + a2*d*d)
rcp r9.x, r9.x

mul r1, r8, r9.xxxx	; Scale with the attenuation
mul r8, r1.y, c11	; Multiply with point_light's diffuse

; ============ Calculate directional light's diffuse ============

mov r1, c0.zzzz		; clear r1
dp3 r1.x, r5, -c1     	; normal dot light (N * L)
lit r1, r1

mad r0, r1.y, c8, r8   	; Multiply with dir_light's diffuse then add point_light's diffuse
mad r0, r9.x, c12, r0  	; Add point_light's ambient * attenuation
add r0, r0, c7		; Add other ambient
min oD0, r0, c0.x     	; output diffuse, clamp if > 1

mov oD1, c0.zzzx   	; output specular as 0

; Copy texture coordinate
mov oT0, v7

